--[[

   Copyright (C) 2007 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 of the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

   Written by Charles Cahoon during Summer of Code 2007
--]]


module("log_util", package.seeall)

----------------
-- Log Module --
----------------

local test_name = "creator"
local test = {}
local test_length = 1
local result = {}
local result_length = 1
local test_fh = nil
local result_fh = nil
local last_connection = -1
local num_connections = 0
local connections = {}

--used to control which connection is being logged
--@param c: connection number
--
local function connection_number(c)
	if last_connection == -1 and c ~= -1 then
		last_connection = c
		connections[c] = c
		num_connections = num_connections + 1
		test[test_length] = "connection con" .. c .. ";"
		test_length = test_length + 1
	elseif last_connection == c then
		return
	else
		last_connection = c	
		connections[c] = c
		num_connections = num_connections + 1
		test[test_length] = "connection con" .. c .. ";"
		test_length = test_length + 1
	end
end

--writes tables to .test and .result files
--
function write_to_files()
	if num_connections > 1 then
		for m_i, m_v in pairs(connections) do
			write_to_test_front("connect (con" .. m_v .. ", localhost, root, , );")
		end
	else
		for i=1,test_length-1 do
			if test[i] ~= nil then
				if string.find(test[i], "^connection", 1) ~= nil then
					for j=i, test_length-1 do
						test[j] = test[j+1]
					end
					test_length = test_length - 1
				end	
			end
		end		
	end		
	test_fh = io.open(test_name .. ".test", "w+")
	result_fh = io.open(test_name .. ".result", "w+")
	for i=1,test_length-1 do
		test_fh:write(test[i] .. "\n")			
	end	
	for i=1,result_length-1 do
		if string.find(result[i], "^#error", 1) == nil then
			result_fh:write(result[i] .. "\n")
		end		
	end	
	test_fh:flush()
	result_fh:flush()
	test_fh:close()
	result_fh:close()
end

--writes to the test file
--@param p: string to be written to file, c: connection number
--
function write_to_test(p, c)
	connection_number(c)
	test[test_length] = p
	test_length = test_length + 1	
end

--writes to the front of the test file
--@param p: string to be written to file
--
function write_to_test_front(p)
	local last, current	
	last = p			
	for k=1,test_length do
		current = test[k]
		test[k] = last
		last = current
	end	
	test_length = test_length + 1
end

--writes to the result file
--@param p: string to be written to file, c: connection number
--
function write_to_result(p)
	result[result_length] = p
	result_length = result_length + 1		
end

--writes to the front of the result file
--@param p: string to be written to file
--
function write_to_result_front(p)
	local last, current	
	last = p			
	for k=1,result_length do
		current = result[k]
		result[k] = last
		last = current
	end	
	result_length = result_length + 1
end

--adds `--error [num]` to last command if error is returned
--@param p: error that should be expected
--
function write_error(p)
	test[test_length] = test[test_length-1]
	test[test_length-1] = "--error " .. p
	test_length = test_length + 1
	
	result[result_length] = result[result_length-1]
	result[result_length-1] = "#error " .. p
	result_length = result_length + 1
end

--removes all errors from test case and results
--
function remove_errors()
	for i=1,test_length-1 do
		if test[i] ~= nil then
			if string.find(test[i], "^--error", 1) ~= nil then
				for j=i, test_length-1 do
					test[j] = test[j+1]
				end
				test_length = test_length - 1
				for k=i, test_length-1 do
					test[k] = test[k+1]
				end
				test_length = test_length - 1
			end	
		end
	end
	for i=1,result_length-1 do
		if result[i] ~= nil then
			if string.find(result[i], "^#error", 1) ~= nil then				
				for j=i, result_length-1 do
					result[j] = result[j+1]
				end
				result_length = result_length - 1
				for k=i, result_length-1 do
					result[k] = result[k+1]
				end
				result_length = result_length - 1
				for m=i, result_length-1 do
					result[m] = result[m+1]
				end
				result_length = result_length - 1
			end	
		end
	end	
end

--discards the last query made
--
function discard_last()
	local temp_query = test[test_length-1]
	
	--discard the query and result set
	if temp_query ~= nil and result_length ~= 1 then
		test[test_length-1] = test[test_length]
		test_length = test_length - 1
		while result[result_length-1] ~= temp_query do
			result[result_length-1] = result[result_length]
			result_length = result_length - 1
		end
		result[result_length-1] = result[result_length]
		result_length = result_length - 1
		
		--discard errors
		temp_query = test[test_length-1]
		if string.find(temp_query, "^--error", 1) ~= nil then
			test[test_length-1] = test[test_length]
			test_length = test_length - 1
			if string.find(result[result_length-1], "^#error", 1) ~= nil then
				result[result_length-1] = result[result_length]
				result_length = result_length - 1
			end
		end
		
		--discard connection information from query
		temp_query = test[test_length-1]
		if string.find(temp_query, "^connection", 1) ~= nil then
			test[test_length-1] = test[test_length]
			test_length = test_length - 1
			last_connection = -1
		end		
	end
end

--returns test table
--@return test table, test table size
--
function get_test()
	return test, test_length
end

--sets test file
--@param p: test name
function set_test_name(p)
	test_name = p
end

--returns result table
--@return result table
--
function get_result()
	return result, result_length
end

function remove_last_query()
	test[test_length-1] = nil
	test_length = test_length - 1
	result[result_length-1] = nil
	result_length = result_length - 1
end

--resets test and result tables
--
function reset_tables()
	test_name = "creator"
	test = {}
	test_length = 1
	result = {}
	result_length = 1
	test_fh = nil
	result_fh = nil
	last_connection = -1
	num_connections = 0
	connections = {}
end
